/*	Copyright 2007 - Xavier Baro (xbaro@cvc.uab.cat)

	This file is part of eapmlib.

    Eapmlib is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or any 
	later version.

    Eapmlib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "Evaluator.h"
#include "math.h"

Evolutive::CEvaluator::CEvaluator(void): m_NumFields(0),m_FieldsNumBits(NULL),m_VarMinValue(NULL),m_VarMaxValue(NULL)
{				
}

Evolutive::CEvaluator::~CEvaluator(void)
{
	if(m_FieldsNumBits)
		delete[] m_FieldsNumBits;
}

int* Evolutive::CEvaluator::GetProblemDesc(int &NumVars)
{
	NumVars=m_NumFields;
	
	return m_FieldsNumBits;
}

void Evolutive::CEvaluator::SetParameterRange(int NumVars,unsigned int *MinVals,unsigned int *MaxVals)
{
	register int i;
	int Range;

	// Remove old data
	if(m_VarMinValue)
		delete[] m_VarMinValue;
	if(m_VarMaxValue)
		delete[] m_VarMaxValue;
	if(m_FieldsNumBits)
		delete[] m_FieldsNumBits;

	// Allocate the new data
	m_VarMinValue=new unsigned int[NumVars];
	m_VarMaxValue=new unsigned int[NumVars];
	m_FieldsNumBits=new int[NumVars];

	// Store the information
	m_NumFields=NumVars;
	memcpy(m_VarMinValue,MinVals,NumVars*sizeof(unsigned int));
	memcpy(m_VarMaxValue,MaxVals,NumVars*sizeof(unsigned int));

	// Store the needed number of bits
	for(i=0;i<NumVars;i++)
	{
		// Calculate the range of values
		Range=m_VarMaxValue[i]-m_VarMinValue[i]+1;

		// Calculate the minimum number of bits to represent this variable
		m_FieldsNumBits[i]=ceil(log((double)Range)/log(2.0));
	}
}

void Evolutive::CEvaluator::SetProblemDesc(int NumVars,int* VarLenght)
{
	//! Remove old data
	if(m_FieldsNumBits)
		delete[] m_FieldsNumBits;

	//! Allocate the new data
	m_FieldsNumBits=new int[NumVars];

	//! Store the information
	m_NumFields=NumVars;
	memcpy(m_FieldsNumBits,VarLenght,NumVars*sizeof(int));
}

void Evolutive::CEvaluator::EvalPopulation(Evolutive::CPopulation *Population)
{
	register int i;
	int PopSize;
	double Score;
	CChromosome *C=NULL;

	//! Retrieve the population size
	PopSize=Population->GetPopulationSize();

	//! Remove the old scores
	Population->ClearScores();

	//! Evalue each individual of the population
	for(i=0;i<PopSize;i++)
	{
		//! Get a pointer to the chromosome
		C=Population->GetChromosomePtr(i);

		//cout << C->ToString();
		//! Evalue the chromosome		
		Score=GetScore(C);	

		//cout << " => " << Score << endl;
		
		//! Adds the score to the socres list
		Population->AddScore(i,Score);
	}
}
